using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using Data.FileManager;
namespace Data.Probabilities
{
    public class ProbabilityData
    {
        //delete this row
        private ArrayList[] probMatrix;
        private double[] genomeMarginalDistribution;
        private double[] CogmarginalDistribution;
        private int numberOfGenomes, numberOfCogs;

        #region constructors
        public ProbabilityData(StreamReader sReader)
        {
            InitObjects(sReader);
            buildUpObjects(sReader);
        }
        #endregion
        #region getters and setters
        public int NumberOfGenomes
        {
            get
            {
                return this.numberOfGenomes;
            }
        }
        #endregion
        #region methods
        private void buildUpObjects(StreamReader sReader)
        {
            Regex reg = new Regex("[0-9]+");
            int sumOfLengths = 0;
            int prevGenomeNo = 0;
            int genomeNo,cogNo, length;

            while (!sReader.EndOfStream)
            {
                if ( this.probMatrix[prevGenomeNo] == null)
                    this.probMatrix[prevGenomeNo] = new ArrayList(this.numberOfCogs);
                do
                {
                    MatchCollection m = reg.Matches(sReader.ReadLine());
                    if (m.Count != 3)
                        throw new Exception("Bad formatting");
                    else
                    {
                        genomeNo = Int32.Parse(m[0].Value);
                        cogNo = Int32.Parse(m[1].Value);
                        length = Int32.Parse(m[2].Value);
                        if (prevGenomeNo == genomeNo)
                            sumOfLengths = sumOfLengths + length;
                        if (this.probMatrix[genomeNo] == null)
                            this.probMatrix[genomeNo] = new ArrayList(this.numberOfCogs);
                        this.probMatrix[genomeNo].Add(new dCell(cogNo, length));
                    }
                } while (prevGenomeNo == genomeNo && !sReader.EndOfStream);

                this.genomeMarginalDistribution[prevGenomeNo] = (1 / (double)this.numberOfGenomes);
                this.probMatrix[prevGenomeNo].TrimToSize();
                foreach (dCell dc in this.probMatrix[prevGenomeNo])
                {
                    dc.Length = dc.Length / sumOfLengths;
                    this.CogmarginalDistribution[dc.CogNo] = this.CogmarginalDistribution[dc.CogNo] + dc.Length;
                }
                sumOfLengths = length;
                prevGenomeNo = genomeNo;
            }
            this.genomeMarginalDistribution[prevGenomeNo] = (1 / (double)this.numberOfGenomes);
        }

        private void InitObjects(StreamReader sReader)
        {
            Regex reg = new Regex("[0-9]+");
            MatchCollection m = reg.Matches(sReader.ReadLine());
            if (m.Count != 2)
            {
                sReader.Close();
                throw new Exception("Bad formatting At InitObjects (ProbabilityData)");
            }
            else
            {
                this.numberOfGenomes = Int32.Parse(m[0].Value);
                this.numberOfCogs = Int32.Parse(m[1].Value);
                this.genomeMarginalDistribution = new double[this.numberOfGenomes];
                this.CogmarginalDistribution = new double[this.numberOfCogs];
                this.probMatrix = new ArrayList[this.numberOfGenomes];
            }
        }

        public double getGenomeMarginalDistribution(int genomeNumber)
        {
            return this.genomeMarginalDistribution[genomeNumber];
        }

        public ArrayList getConditionalDistribuationOfGenome(int genomeNum)
        {
            return this.probMatrix[genomeNum];
        }
        #endregion
    }
}
